/**
 * 工具包
 */
import config from '../config'
/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行，false 表非立即执行
 */
export function debounce(func: Function, wait = 50, immediate: Boolean) {
  let timeout: any
  return function (this: any) {
    const context = this
    // eslint-disable-next-line prefer-rest-params
    const args = arguments

    if (timeout) clearTimeout(timeout)
    if (immediate) {
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) func.apply(context, args)
    } else {
      timeout = setTimeout(() => {
        func.apply(context, args)
      }, wait)
    }
  }
}

/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版，2 表定时器版
 */
export function throttle(fn: Function, delay: number) {
  let flag = true
  return (...args: any) => {
    if (flag) {
      flag = false
      fn(...args)
      setTimeout(() => {
        flag = true
      }, delay)
    }
  }
}

// 获取页面的名称作为token key
export function getTokenKeyForPage() {
  const { pathname } = window.location
  let htmlName = pathname.substring(1, pathname.indexOf('.'))
  // 首字母大写
  htmlName = htmlName.charAt(0).toUpperCase() + htmlName.slice(1)
  // 取页面名来区分不同的token
  const tokenKeyPage = config.TOKEN_KEY + (htmlName ? `-${htmlName}` : '-Index')
  return tokenKeyPage
}
// 获取iframe父级URL
export function getParentUrl() {
  let url = ''
  if (parent !== window) {
    try {
      url = parent.location.host
    } catch (e) {
      url = document.referrer
    }
  }
  return url
}
export function dataURLtoFile(dataUrl: any, filename = 'file') {
  if (typeof dataUrl === 'object') {
    return new File([dataUrl], `${filename}.jpg`, { type: 'jpg' })
  }
  const arr = dataUrl.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const suffix = mime.split('/')[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], `${filename}.${suffix}`, { type: mime })
}
export const getRandomStr = () => {
  return new Date().getTime() + Math.random().toString(16).slice(2)
}

export function isFunction(fun: any) {
  return Object.prototype.toString.call(fun) === '[object Function]'
}
export function isObject(fun: any) {
  return Object.prototype.toString.call(fun) === '[object Object]'
}

interface jsonParams {
  url: string
  data: any
}
export function jsonp({ url, data }: jsonParams): any {
  if (!url) {
    throw new Error('url is necessary')
  }
  try {
    return new Promise((resolve) => {
      const callback: string = `CALLBACK${Math.random().toString().substr(9, 18)}`
      const JSONP: any = document.createElement('script')
      JSONP.setAttribute('type', 'text/javascript')
      const headEle = document.getElementsByTagName('head')[0]
      let ret: string = ''
      if (data) {
        if (typeof data === 'string') {
          ret = `&${data}`
        } else if (typeof data === 'object') {
          // eslint-disable-next-line guard-for-in
          for (const key in data) ret += `&${key}=${encodeURIComponent(data[key])}`
        }
      }
      ret += `&_time=${Date.now()}`
      JSONP.src = `${url}?callback=${callback}${ret}` as string
      ;(window as any)[callback] = (result: any) => {
        resolve(result)
        headEle.removeChild(JSONP)
        delete (window as any)[callback]
      }
      headEle.appendChild(JSONP)
    })
  } catch (err) {
    console.log(err)
  }
}

// 获取链接参数
export function getQueryString(name: string, url?: string) {
  const href = url || window.location.href
  if (href.includes('?') && href.includes(name)) {
    const arr: any[] = href
      .split('?')
      .filter((x) => x.includes(name))
      .join()
      .split('&')
    return arr
      .find((item) => {
        return item.includes(name)
      })
      .split('=')[1]
  }
  return null
}

/**
 * 获取URL参数并以对象数据形式返回
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url: string) {
  url = url || window.location.href
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj: any = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}
// 生成uuid
export function uuid(len?: number, radix?: number) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  // eslint-disable-next-line prefer-const
  let uuid: string[] = []
  let i
  radix = radix || chars.length

  if (len) {
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
  } else {
    let r
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'

    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}
// 将rgba字符串对象转化为rgba对象
export function rgba2Obj(rgba = '') {
  const reg = /rgba\((\d+),(\d+),(\d+),(\d+)\)/g
  let rgbaObj: any = { r: 0, g: 0, b: 0, a: 0 }

  rgba.replace(reg, (_m, r, g, b, a) => {
    rgbaObj = { r, g, b, a }
    return rgba
  })
  return rgbaObj
}

export function formatTime(fmt: string, dateObj?: any) {
  const date = dateObj || new Date()
  const o: any = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length))
  }
  for (const k in o) {
    if (new RegExp(`(${k})`).test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
      )
    }
  }
  return fmt
}

// 金额千分位
export const currency = (v: any) => {
  const [n, d = []] = v.toString().split('.')
  return [n.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')].concat(d).join('.')
}

// 时间戳格式化
export const timestampToTime = (timestamp: any, type?: any) => {
  const date = new Date(timestamp) // 时间戳为10位需*1000，时间戳为13位的话不需乘1000
  const Y = `${date.getFullYear()}-`
  const M = `${date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1}-`
  const D = date.getDate() < 10 ? `0${date.getDate()} ` : `${date.getDate()}`
  const h = date.getHours() < 10 ? `0${date.getHours()}:` : `${date.getHours()}:`
  const m = date.getMinutes() < 10 ? `0${date.getMinutes()}:` : `${date.getMinutes()}:`
  const s = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
  if (type === 'second') {
    return `${Y + M + D} ${h}${m}${s}`
  }
  return Y + M + D
}

/**
 * 对象数组去重,type表示对象里面的一个属性
 */
export const uniqueFun = (arr: any[], type: any) => {
  const res = new Map()
  return arr.filter((a) => !res.has(a[type]) && res.set(a[type], 1))
}

//  数组转树形,思路也是先把数据转成Map去存储，之后遍历的同时借助对象的引用，直接从Map找对应的数据做存储。不同点在遍历的时候即做Map存储,有找对应关系。性能会更好。
// 空间复杂度O(n)
export function arrayToTree(items: any[]) {
  const result: any[] = [] // 存放结果集
  const itemMap: Object = {} //
  for (const item of items) {
    const id = item.id
    const pid = item.pid

    if (!itemMap[id]) {
      itemMap[id] = {
        children: [],
      }
    }

    itemMap[id] = {
      ...item,
      children: itemMap[id]['children'],
    }

    const treeItem: any = itemMap[id]

    if (pid === 0) {
      result.push(treeItem)
    } else {
      if (!itemMap[pid]) {
        itemMap[pid] = {
          children: [],
        }
      }
      itemMap[pid].children.push(treeItem)
    }
  }
  return result
}
